// InputHandler.cs
//

using System.Html;
using System.Collections.Generic;
using Moonbeam.Core;
using System;

namespace Moonbeam.Input
{
    public class InputHandler
    {
        #region properties

        public KeyboardState CurrentKeyboardState;
        public KeyboardState PreviousKeyboardState;

        public MouseState CurrentMouseState;
        public MouseState PreviousMouseState;

        #endregion

        #region fields

        List<int> _keyBuffer = new List<int>(2);
        List<int> _clickBuffer = new List<int>(2);
        Vector2 mousePosition=new Vector2(0,0);        
        ClientRect rect = null;
        Element root = null;
        CanvasElement drawingSurface;

        #endregion

        public InputHandler(WindowInstance windowInstance)
        {
            CurrentKeyboardState = new KeyboardState();
            PreviousKeyboardState = new KeyboardState();
            
            CurrentMouseState = new MouseState();
            PreviousMouseState = new MouseState();

            #region setup Mouse capture bits
            
            drawingSurface = ((GraphicsDevice)GameComponentManager.Instance.GetComponent(typeof(GraphicsDevice))).GetRenderingWindow();

            root = Document.DocumentElement;
            
            //Script# does not expose canvas.conext.getBoundingClientRect(), so we just insert JS that doe the job.
            Script.Literal("this._rect = this._drawingSurface.getBoundingClientRect()");

            #endregion

            #region Bind input capture events

            windowInstance.AddEventListener("keydown", OnKeyPress, false);
            windowInstance.AddEventListener("click", OnMouseClick, false);
            windowInstance.AddEventListener("dblclick", OnMouseClick, false);
            windowInstance.AddEventListener("mousedown", OnMouseClick, false);

            drawingSurface.AddEventListener("mousemove", OnMouseMove, false);

            #endregion
        }

        internal void Update()
        {                       
            PreviousKeyboardState = CurrentKeyboardState;
            CurrentKeyboardState._SetKeys(_keyBuffer);

            PreviousMouseState = CurrentMouseState;
            CurrentMouseState._SetMousePosition(mousePosition);
            CurrentMouseState._SetButtons(_clickBuffer);
        }

        #region Keyboard Event Handlers

        void OnKeyPress(ElementEvent e)
        {
            _keyBuffer.Add(e.KeyCode);
        }

        #endregion

        #region Mouse Event Handlers

        void OnMouseClick(ElementEvent e)
        {
            _clickBuffer.Add(e.Button);
        }

        void OnMouseMove(ElementEvent e)
        {

            if (rect==null)
            {
                //set to 0,0
                mousePosition.x = 0;
                mousePosition.y = 0;
            }
            else
            {
                //Script# does not expose canvas.conext.getBoundingClientRect(), so we just insert JS that doe the job.
                Script.Literal("this._rect = this._drawingSurface.getBoundingClientRect()");
                Script.Literal("this._mousePosition.x = e.clientX - this._rect.left - this._root.scrollLeft");
                Script.Literal("this._mousePosition.y = e.clientY - this._rect.top - this._root.scrollTop");                
            }
        }

        #endregion
    }
}
